package org.toycode.logindemo.application.config;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement;
import org.toycode.logindemo.entity.Article;
import org.toycode.logindemo.entity.Paper;
import org.toycode.logindemo.entity.Task;

/**
 * Configurations for data table relevant services.
 *
 * @author <a href="mailto:DL88250@gmail.com">Liang Ding</a>
 * @version 1.0.0.0, Sep 1, 2009
 */
@XmlRootElement(name = "data-table")
public class Config {

    public static Config dataTableConfig;
    @XmlElements(@XmlElement(type = Entity.class, name = "entity"))
    public List<Entity> entities;

    /**
     * Generates a sample config.xml.
     *
     * @throws JAXBException jaxb exception
     */
    public static void genSampleConfig() throws JAXBException {
        final JAXBContext jc = JAXBContext.newInstance(Config.class);
        final Marshaller m = jc.createMarshaller();
        dataTableConfig = new Config();
        // types:
        final List<Entity> entityList = new ArrayList<Entity>();
        dataTableConfig.entities = entityList;

        final Entity task = new Entity();
        task.clazz = Task.class.getName();
        task.displayName = "Task";
        final List<Prop> taskProps = new ArrayList<Prop>();

        final Prop id = new Prop();
        id.displayName = "Id";
        id.name = "id";
        id.type = "Long";
        id.getter = "getId";
        taskProps.add(id);

        final Prop owner = new Prop();
        owner.displayName = "Owner";
        owner.name = "owner";
        owner.type = "String";
        owner.getter = "getOwner";
        taskProps.add(owner);

        final Prop description = new Prop();
        description.displayName = "Description";
        description.name = "description";
        description.type = "String";
        description.getter = "getDescription";
        taskProps.add(description);

        final Prop progressDescription = new Prop();
        progressDescription.displayName =
                "Progress";
        progressDescription.name = "progressDescription";
        progressDescription.type = "String";
        progressDescription.getter = "getProgressDescription";
        taskProps.add(progressDescription);

        task.props = taskProps;
        entityList.add(task);
        ////////////////////////////////////////////////////////////////////////
        final Entity article = new Entity();
        article.clazz = Article.class.getName();
        article.displayName = "Article";
        final List<Prop> articleProps = new ArrayList<Prop>();

        final Prop author = new Prop();
        author.displayName = "Author";
        author.name = "author";
        author.type = "String";
        author.getter = "getAuthor";
        articleProps.add(author);

        final Prop publishDateProp = new Prop();
        publishDateProp.displayName = "发布日期";
        publishDateProp.name = "publishDate";
        publishDateProp.type = "String";
        publishDateProp.getter = "getPublishDate";
        articleProps.add(publishDateProp);

        article.props = articleProps;
        entityList.add(article);
        ////////////////////////////////////////////////////////////////////////
        final Entity paper = new Entity();
        paper.clazz = Paper.class.getName();
        paper.displayName = "Paper";
        final List<Prop> paperProps = new ArrayList<Prop>();

        final Prop paperAuthor = new Prop();
        paperAuthor.displayName = "Author";
        paperAuthor.name = "author";
        paperAuthor.type = "String";
        paperAuthor.getter = "getAuthor";
        paperProps.add(paperAuthor);

        final Prop publishDateProp2 = new Prop();
        publishDateProp2.displayName = "Publish Date";
        publishDateProp2.name = "publishDate";
        publishDateProp2.type = "String";
        publishDateProp2.getter = "getPublishDate";
        paperProps.add(publishDateProp2);

        final Prop status = new Prop();
        status.displayName = "Status";
        status.name = "status";
        status.type = "String";
        status.getter = "getStatus";
        paperProps.add(status);

        final Prop title = new Prop();
        title.displayName = "Title";
        title.name = "title";
        title.type = "String";
        title.getter = "getTitle";
        paperProps.add(title);

        final Prop summary = new Prop();
        summary.displayName = "Summary";
        summary.name = "summary";
        summary.type = "String";
        summary.getter = "getSummary";
        paperProps.add(summary);

        final Prop score = new Prop();
        score.displayName = "Score";
        score.name = "score";
        score.type = "int";
        score.getter = "getScore";
        paperProps.add(score);

        paper.props = paperProps;
        entityList.add(paper);

        m.setProperty(m.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        m.marshal(dataTableConfig, new File("src/main/resources/data-table.xml"));
    }

    /**
     * Loads the config.xml.
     *
     * @throws JAXBException jaxb exception
     */
    public synchronized static void load() throws Exception {
        final JAXBContext jc = JAXBContext.newInstance(Config.class);
        final Unmarshaller m = jc.createUnmarshaller();

        final ClassLoader cl = Config.class.getClassLoader();
        final URL url = cl.getResource("data-table.xml");

        Config.dataTableConfig = (Config) m.unmarshal(new File(url.toURI()));
    }

    public static void main(String[] args) throws JAXBException {
        genSampleConfig();
    }
}
